package css.sword.service.impl;

import com.fastdfs.domain.StorePath;
import com.fastdfs.proto.storage.*;
import com.fastdfs.service.DefaultGenerateStorageClient;
import com.fastdfs.service.FastFileStorageClient;
import com.itextpdf.text.*;
import com.itextpdf.text.pdf.PdfReader;
import com.itextpdf.text.pdf.PdfWriter;
import com.itextpdf.text.pdf.RandomAccessFileOrArray;
import com.itextpdf.text.pdf.codec.TiffImage;
import css.sword.base.BaseMapper;
import css.sword.base.impl.BaseServiceImpl;
import css.sword.entity.DfsBaseInfo;
import css.sword.entity.DfsRelationShip;
import css.sword.entity.DfsTransferStatus;
import css.sword.mapper.DfsBaseInfoMapper;
import css.sword.mapper.DfsRelationShipMapper;
import css.sword.service.DfsTransferStatusService;
import css.sword.service.FileService;
import css.sword.service.SnowflakeIdWorker;
import css.sword.util.*;
import org.apache.commons.codec.digest.DigestUtils;
import org.apache.commons.io.FilenameUtils;
import org.apache.commons.io.IOUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.net.InetAddress;
import java.net.URLConnection;
import java.net.URLEncoder;
import java.net.UnknownHostException;
import java.time.Instant;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.util.*;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;

import static css.sword.util.LibreUtils.doDocToFdpLibre;

@Service("fileServiceImpl")
public class FileServiceImpl extends BaseServiceImpl<ReType, Long> implements FileService {

    Logger log = LoggerFactory.getLogger(FileServiceImpl.class);

    private static HashMap<String,byte[]> redFileMap=new HashMap<String,byte[]>();

    @Autowired
    DfsTransferStatusService dfsTransferStatusService;

    @Autowired
    protected DefaultGenerateStorageClient defaultGenerateStorageClient;
    @Autowired
    SnowflakeIdWorker snowflakeIdWorker;
    @Autowired
    protected FastFileStorageClient storageClient;

    @Autowired
    private DfsBaseInfoMapper dfsBaseInfoMapper;
    @Autowired
    private DfsRelationShipMapper dfsRelationShipMapper;


    @Value("${wpsServer}")
    private String wpsServer;

    @Override
    public BaseMapper<ReType, Long> getMappser() {
        return null;
    }

    @Value("${fdfs.secret-key}")
    private  String secretKey;

    @Autowired
    private JdbcTemplate jdbcTemplate;

    @Override
    @Transactional
    public String upload(MultipartFile multipartFile, File file, Map<String, String> data, boolean taohong, boolean validateMd5,boolean isDelete) {
        InputStream in =null;
        DfsBaseInfo record = new DfsBaseInfo();
        DfsRelationShip drs = new DfsRelationShip();
        setInsertDfsBaseInfo(record, data);
        setInsertDfsRelationShip(drs, data);
        DfsBaseInfo dfsBaseInfo = null;
        StorePath storePath=null;
        if (!validateMd5 || (validateMd5 && (dfsBaseInfo = dfsBaseInfoMapper.selectByMd5Val(record)) == null)) {
            try {
                if(file==null)
                    storePath = storageClient.uploadFile(multipartFile.getInputStream(), Long.parseLong(data.get("fileSize")), data.get("fileExt"), null);
                else {
                    in = new FileInputStream(file);
                    storePath = storageClient.uploadFile(in, Long.parseLong(data.get("fileSize")), data.get("fileExt"), null);
                }
                record.setFileId(storePath.getFullPath());
                record.setGroupName(storePath.getGroup());
                int count = dfsBaseInfoMapper.insert(record);
                //log.debug(count + "dddddddddddddddddddddfsBaseInfoMapper");
            } catch (IOException e1) {
                e1.printStackTrace();
                log.error(e1.getMessage());
            }finally{
                if(in!=null) {
                    try {
                        in.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }
        }
        data.put("url",record.getMd5Val()+"@"+record.getFileSize());
        String isDel=StringUtils.isNotEmpty(data.get("isdel"))?data.get("isdel"):"";
        if(file!=null&&isDelete)
            file.delete();
        if(taohong&&dfsBaseInfo!=null){
            return "0";
        }
        drs.setId(snowflakeIdWorker.nextId());
        drs.setFileSize(record.getFileSize());
        int count = insertDfsRelationShip(drs);
        //log.debug(count + "dddddddddddddddddddddinsertSelective");
        return storePath.getFullPath();
    }

    public static void setInsertDfsRelationShip(DfsRelationShip drs, Map<String, String> data) {
        drs.setFileSrcSystem(data.get("moduleName"));
        drs.setUserDfsId(data.get("userID"));
        drs.setFileSrcName(data.get("fileSrcName").replaceAll("(\\r\\n|\\r|\\n|\\n\\r)",""));
        drs.setIsDel("0");
        drs.setIsTemp("0");
        drs.setFileType(data.get("fileType"));
        drs.setMd5Path(data.get("md5") + "@" + data.get("fileSize"));
        drs.setSafeKey(data.get("secretKey"));
        drs.setSrcIpAddr(data.get("requestIP"));
        drs.setXgrDm(data.get("userID"));
        drs.setXgrq(LocalDateTime.now());
        drs.setLrrDm(data.get("userID"));
        drs.setLrrq(LocalDateTime.now());
        drs.setFileSize(Long.valueOf(data.get("fileSize")));
        drs.setIsWpsSecure(StringUtils.isEmpty(data.get("isWpsSecure"))?"0":data.get("isWpsSecure"));
        drs.setFileType(URLConnection.getFileNameMap().getContentTypeFor(data.get("fileSrcName")));
        drs.setIsWpsSecure(data.get("isWpsSecure")!=null?data.get("isWpsSecure"):"0");
    }

    public static void setInsertDfsBaseInfo(DfsBaseInfo record, Map<String, String> data) {
        record.setMd5Val(data.get("md5"));
        record.setFileExt(data.get("fileExt"));
        record.setFileSize(Long.parseLong(data.get("fileSize")));
        record.setFileDownloadCount(0L);
        record.setRelateNum(0L);
        record.setIsWpsSecure(StringUtils.isEmpty(data.get("isWpsSecure"))?"0":data.get("isWpsSecure"));
        record.setLrrDm(data.get("userID"));
        record.setLrrq(LocalDateTime.now());
        record.setXgrDm(data.get("moduleName"));
        record.setXgrq(LocalDateTime.now());
        record.setIsWpsSecure(data.get("isWpsSecure")!=null?data.get("isWpsSecure"):"0");
    }

    @Override
    public byte[] download(String fileId) {
        return new byte[0];
    }

    @Override
    public boolean isValid(String fileExtName) {
        return true;
    }

    @Override
    public DfsBaseInfo md5Check(DfsBaseInfo md5) {
        return dfsBaseInfoMapper.selectByMd5Val(md5);
    }

    @Override
    @Transactional
    public int insertDfsRelationShip(DfsRelationShip dfsRelationShip) {
        int count=dfsRelationShipMapper.insertSelective(dfsRelationShip);
        dfsRelationShip.setFileSize(Long.valueOf(dfsRelationShip.getMd5Path().substring(dfsRelationShip.getMd5Path().indexOf("@")+1)));
        dfsRelationShip.setMd5Path(dfsRelationShip.getMd5Path().substring(0, dfsRelationShip.getMd5Path().indexOf("@")));
        dfsBaseInfoMapper.updateRelateNum(dfsRelationShip);
        return count;
    }

    @Override
    public DfsRelationShip selectByMd5Path(DfsRelationShip drs) {
        return dfsRelationShipMapper.selectByMd5Path(drs);
    }

    @Override
    public void downloadStream(DfsRelationShip drs, HttpServletResponse response, boolean isIE,boolean convertDocx,boolean isPreview,boolean isWebOffice,String wordWaterMark,String caToken,boolean isWpsSecure,String waterMark) throws IOException {

        drs.setMd5Path(drs.getMd5Path().substring(0, drs.getMd5Path().indexOf("@")));
        dfsBaseInfoMapper.updateClick(drs);
        OutputStream out = response.getOutputStream();
        StorePath storePath = StorePath.praseFromUrl(drs.getFileId());
        String fileName = drs.getFileSrcName();

        String fileExt= drs.getFileId().substring(drs.getFileId().lastIndexOf(".")+1);
        fileName=FilenameUtils.getBaseName(fileName)+"."+fileExt;
        log.debug("替换的前端可能传错的filesrcname值"+fileName);
        if(fileName.toLowerCase().endsWith(".doc")&&convertDocx)
            fileName+="x";

        if(FilenameUtils.getExtension(fileName).equals("")){
            byte[] abyte=storageClient.downloadFile(storePath.getGroup(), storePath.getPath(),0,10,new DownloadByteArray());
            fileName+="."+FileType.getFileType(abyte);
        }
        if(isWebOffice)
            log.debug(fileName+" webofficeweboffice");
        if (isIE)
            ;
        else
            fileName=new String(fileName.getBytes("UTF-8"), "ISO8859_1");
        log.debug(fileName);

        if(isPreview)
           response.addHeader("Content-Disposition", "inline;filename=\"" + fileName+"\"");
        else
           response.addHeader("Content-Disposition", "attachment;filename=\"" + fileName+"\"");
       // response.setHeader("PDF-TITLE",fileName);


        if(!convertDocx&&StringUtils.isEmpty(wordWaterMark)&&StringUtils.isEmpty(caToken)&&StringUtils.isEmpty(waterMark)) {
            response.addHeader("Content-Length", drs.getFileSize() + "");
            log.debug("Content-Length"+drs.getFileSize() + "");
        }
        if(!fileName.endsWith(".pdf")&&!fileName.endsWith(".PDF"))
            waterMark="";
        if(isWebOffice)
            isWpsSecure=false;
        storageClient.downloadFile(storePath.getGroup(), storePath.getPath(), new DownloadStream(out,waterMark,convertDocx,wordWaterMark,response,caToken,isWpsSecure,false));
        out.close();
    }

    @Override
    public void downloadPackageStream(String[] md5Paths, String[] fileNames, String zipName, HttpServletResponse response, boolean isIE,String waterMark) throws IOException {
        String fileName;
        zipName=zipName.replaceAll("%28","(").replaceAll("%29",")").replaceAll("%27","'").replaceAll("%21","!").replaceAll("%7E","~").replaceAll("%40","@").replaceAll("%23","#").replaceAll("%25","%").replaceAll("%26","&").replaceAll("%2B","+").replaceAll("%2A","*");
        //zipName= URLDecoder.decode(zipName,"UTF-8");
        log.debug("111aaaaaaaaaaaaaaa"+zipName);
        if (isIE)
            fileName = URLEncoder.encode(zipName, "UTF-8");
        else
            fileName=new String(zipName.getBytes("UTF-8"), "ISO8859_1");
        response.addHeader("Content-Disposition", "attachment;filename=\"" + fileName+"\"");
        HashMap<String, String> hashMap = new LinkedHashMap<String, String>();
        // 开始往ZOS流里存数据
        OutputStream out = response.getOutputStream();
        ZipOutputStream zos = new ZipOutputStream(out);
        boolean flag=false;
        if(fileNames==null){
            fileNames = new String[md5Paths.length];
            flag=true;
        }

        for(int i=0;i<fileNames.length;i++){
            DfsRelationShip dfsRelationShip=new DfsRelationShip();
            dfsRelationShip.setMd5Path(md5Paths[i]);
            dfsRelationShip= dfsRelationShipMapper.selectByMd5Path(dfsRelationShip);
            if(flag) {
                fileNames[i] = dfsRelationShip.getFileSrcName();
            }
            if (hashMap.containsKey(fileNames[i])) {
                for (int j = 1; j < 64; j++) {
                    String tempFileName = FilenameUtils.getBaseName(fileNames[i]) + "(" + j + ")."
                            + FilenameUtils.getExtension(fileNames[i]);
                    if (!hashMap.containsKey(tempFileName)) {
                        hashMap.put(tempFileName, dfsRelationShip.getFileId());
                        break;
                    }
                }
            } else
                hashMap.put(fileNames[i], dfsRelationShip.getFileId());
        }
        long startTime = System.currentTimeMillis();
        // 解决浏览器等待ZIP压缩延时的问题
        for (Map.Entry<String, String> entry : hashMap.entrySet()) {
            log.debug(entry.getKey() + "----" + entry.getValue());
            zos.putNextEntry(new ZipEntry(entry.getKey()));
            StorePath storePath = StorePath.praseFromUrl(entry.getValue());
            if(storePath.getPath().endsWith("pdf")||storePath.getPath().endsWith("PDF"))
                storageClient.downloadFile(storePath.getGroup(), storePath.getPath(), new DownloadStream(zos,waterMark,false,null,null,"",false,true));
            else
                storageClient.downloadFile(storePath.getGroup(), storePath.getPath(), new DownloadStream(zos,"",false,null,null,"",false,true));
        }
        log.debug("压缩耗时: " + (System.currentTimeMillis() - startTime));
        zos.flush();
        zos.close();
        out.close();
    }

    @Override
    public void convertDocx2PdfStream(DfsRelationShip drs,String waterMark, HttpServletResponse response) throws IOException {
        drs.setMd5Path(drs.getMd5Path().substring(0, drs.getMd5Path().indexOf("@")));
        dfsBaseInfoMapper.updateClick(drs);
        OutputStream out = response.getOutputStream();
        StorePath storePath = StorePath.praseFromUrl(drs.getFileId());

        String fileName =  drs.getFileSrcName().substring(0,drs.getFileSrcName().lastIndexOf(".")+1)+"pdf";
        response.addHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(fileName, "UTF-8"));
        storageClient.downloadFile(storePath.getGroup(), storePath.getPath(), new ConvertDocx2PdfStream(out,waterMark));
        out.flush();
        out.close();
    }

    @Override
    public String mergeRedDocx2PdfStream(DfsRelationShip drs,String mergeRedPdfPath,Map<String,String> data, String waterMark,String convertMode,String forceRefresh) throws IOException, DocumentException {
        byte[] redFile;
        String md5Path=drs.getMd5Path();
        String srcPdfPath=drs.getPdfPath();
        log.debug(srcPdfPath);
        if(StringUtils.isNotEmpty(forceRefresh)&&forceRefresh.equals("1"))
            srcPdfPath="";

        log.debug(srcPdfPath+"ccccccccccccccccc");
        Long srcFileSize=drs.getFileSize();
        String fileExt=FilenameUtils.getExtension(drs.getFileSrcName());
        String fileSrcName =  drs.getFileSrcName().substring(0,drs.getFileSrcName().lastIndexOf(".")+1)+"pdf";
        drs.setMd5Path(drs.getMd5Path().substring(0, drs.getMd5Path().indexOf("@")));
        dfsBaseInfoMapper.updateClick(drs);
        drs.setMd5Path(md5Path);
        StorePath storePath = StorePath.praseFromUrl(drs.getFileId());

        drs.setMd5Path(mergeRedPdfPath);
        if(redFileMap.containsKey(mergeRedPdfPath))
            redFile=redFileMap.get(mergeRedPdfPath);
        else{
            drs=selectByMd5Path(drs);
            StorePath redStorePath = StorePath.praseFromUrl(drs.getFileId());
            DownloadByteArray callback = new DownloadByteArray();
            redFile=storageClient.downloadFile(redStorePath.getGroup(),redStorePath.getPath(),callback);
            redFileMap.put(mergeRedPdfPath,redFile);
        }
        String srcTempFile =
                System.getProperty("java.io.tmpdir") + "/upload_tmp" + UUID.randomUUID() + "."+fileExt;
        File tempFilePdf=new File(System.getProperty("java.io.tmpdir") + "/upload_tmp" + UUID.randomUUID() + ".pdf");
        Map data1 = new HashMap();
        if(md5Path.endsWith("@0")){
            Document document = new Document();
            try (OutputStream out1=new FileOutputStream(tempFilePdf)){
                PdfWriter writer = PdfWriter.getInstance(document,out1);
                document.open();
                document.add(new Paragraph(" "));
                document.close();
                writer.close();
            }catch (DocumentException e) {
                e.printStackTrace();
            } catch (FileNotFoundException e) {
                e.printStackTrace();
            }
        }else if((fileExt.equalsIgnoreCase("docx")||fileExt.equalsIgnoreCase("doc")||fileExt.equalsIgnoreCase("wps"))&&StringUtils.isEmpty(srcPdfPath)) {

            if(convertMode.equals("wps")) {
                //PdfUtils.wps_word2pdf(srcTempFile, tempFilePdf.getAbsolutePath());
               //String  convertPdfPath=HttpClientUtil.getInstance().httpGet("https://127.0.0.1:8443/file/convertWps2Pdf?md5Path="+md5Path,null);
                String[] wpsArray=wpsServer.split(",");
                int length=wpsArray.length;
                int i=new Random().nextInt(length);
                String wpsHost=wpsArray[i];

                log.info("wps windows 转版服务器 wpsHost:{},md5Path:{}," +
                        "md5PathHttpClient",
                    wpsHost,md5Path);
                String convertPdfPath =HttpClientUtil.getInstance().httpGet(wpsHost+"/file/convertWps2Pdf?md5Path="+md5Path,null);

               drs.setMd5Path(convertPdfPath);
               drs=selectByMd5Path(drs);
               storePath = StorePath.praseFromUrl(drs.getFileId());
               storageClient.downloadFile(storePath.getGroup(), storePath.getPath(), new DownloadFileWriter(tempFilePdf.getAbsolutePath()));
            }else {
                storageClient.downloadFile(storePath.getGroup(), storePath.getPath(), new DownloadFileWriter(srcTempFile));
                doDocToFdpLibre(new File(srcTempFile), tempFilePdf);
                new File(srcTempFile).delete();
                try(InputStream in =new FileInputStream(tempFilePdf)) {
                    String md5 = Md5Util.md5(in);
                    Long fileSize = tempFilePdf.length();
                    data.put("md5", md5);
                    data.put("fileSize", fileSize + "");
                    data.put("fileSrcName", fileSrcName);
                    data.put("fileExt", "pdf");
                    data.put("isdel","0");
                    data1.put("md5Path",data.get("md5")+"@"+ data.get("fileSize"));
                } catch (FileNotFoundException e) {
                    e.printStackTrace();
                } catch (IOException e) {
                    e.printStackTrace();
                }
                String pdfFileId=upload(null, tempFilePdf, data, true, true,false);
                data1.put("md5",md5Path.substring(0, md5Path.indexOf("@")));
                data1.put("fileSize",srcFileSize);
                dfsBaseInfoMapper.updatePdfPath(data1);
            }
        }else if(fileExt.equalsIgnoreCase("pdf")){
            storageClient.downloadFile(storePath.getGroup(), storePath.getPath(), new DownloadFileWriter(tempFilePdf.getAbsolutePath()));
        }else if((fileExt.equalsIgnoreCase("docx")||fileExt.equalsIgnoreCase("doc")||fileExt.equalsIgnoreCase("wps"))&&StringUtils.isNotEmpty(srcPdfPath)){
            drs.setMd5Path(srcPdfPath);
            drs=selectByMd5Path(drs);
            storePath = StorePath.praseFromUrl(drs.getFileId());
            storageClient.downloadFile(storePath.getGroup(), storePath.getPath(), new DownloadFileWriter(tempFilePdf.getAbsolutePath()));
        }
        InputStream in;
        if(StringUtils.isNotEmpty(waterMark)) {
            ByteArrayOutputStream os = new ByteArrayOutputStream();
            PdfUtils.waterMarkerText(new PdfReader(new FileInputStream(tempFilePdf)), os, waterMark);
            in = new ByteArrayInputStream(os.toByteArray());
        }else{
            in=new FileInputStream(tempFilePdf);
        }
        File tempFile = new File(
                System.getProperty("java.io.tmpdir") + "/upload_tmp" + UUID.randomUUID() + ".pdf");
        OutputStream out2=new BufferedOutputStream(new FileOutputStream(tempFile));
        PdfUtils.mergeRed(in,redFile,out2);
        out2.close();
        in.close();
        tempFilePdf.delete();
        String md5= Md5Util.md5(new FileInputStream(tempFile));
        Long fileSize=tempFile.length();
        data.put("md5",md5);
        data.put("fileSize",fileSize+"");
        data.put("fileSrcName",fileSrcName);
        data.put("fileExt","pdf");
        return upload(null,tempFile,data,true,true,true);
    }

    @Transactional
    @Override
    public void fileTransfer(File file, DfsBaseInfo record, DfsRelationShip drs) {
        StorePath storePath = null;
        try {
            storePath = storageClient.uploadFile(new BufferedInputStream(new FileInputStream(file)), drs.getFileSize(), record.getFileExt(), null);
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }
        record.setFileId(storePath.getFullPath());
        record.setGroupName(storePath.getGroup());
        dfsBaseInfoMapper.insert(record);
        drs.setId(snowflakeIdWorker.nextId());
        insertDfsRelationShip(drs);
        if(!file.getAbsolutePath().contains("z:\\fileservice\\store")){
            log.debug("deleteddddddddddddddddddddddddddddddddd"+file.getAbsolutePath());
            file.delete();
        }
    }

    @Override
    public void fileListTransfer(Map<String, Object> fileMap, String info) {

        long startTime=System.currentTimeMillis();
        String bussinessId=fileMap.get("id")!=null?fileMap.get("id").toString():"";
        log.debug(fileMap.get("id") + "\t");

        String fileName=fileMap.get("file_name")!=null?fileMap.get("file_name").toString():"文件名为空";
        fileName=fileName.replaceAll("\n","").replaceAll("\r","");
        log.debug(fileName + "\t");

        String fileExt=fileMap.get("extention")!=null?fileMap.get("extention").toString():"123";

        if(fileExt.startsWith(".")){
            fileExt=fileExt.substring(1);
        }
        String savePath=fileMap.get("save_path")!=null?fileMap.get("save_path").toString():"";
        String realPath=StringUtils.splitFileId(fileMap.get("save_path").toString().substring(4));
        log.debug(fileMap.get("save_path") + "\t");
        log.debug(realPath + "\t");

        String moduleName="szoa1"+info;
        String userId=fileMap.get("user_id")!=null?fileMap.get("user_id").toString():"";
        Date createDate= null;
        try{

            try {
                createDate = fileMap.get("save_time") != null ? DateUtils.parseDate(fileMap.get("save_time").toString(), DateUtils.DATE_PATTERNS) : new Date();
            }catch (Exception e){
                createDate = fileMap.get("save_time") != null ? DateUtils.parseDate(fileMap.get("save_time").toString(), DateUtils.DATE_PATTERNS) : new Date();
            }

        File file=new File("z:\\fileservice\\store\\"+realPath);

        boolean flag=false;
//        if(fileExt.equalsIgnoreCase("doc")){
//            File tempFile = new File(
//                    System.getProperty("java.io.tmpdir") + "/upload_tmp" + UUID.randomUUID() + ".docx");
//            try {
//
//                //PdfUtil.convertDocFmt(file.getAbsolutePath(),tempFile.getAbsolutePath(),12);
//                file=tempFile;
//                flag=true;
//                fileExt="docx";
//            } catch (Exception e) {
//                e.printStackTrace();
//            }
//        }
        Long fileSizeLong=file.length();
        DfsBaseInfo dfsBaseInfo=new DfsBaseInfo();
        InputStream in= null;
        String md5="";
        in = new BufferedInputStream(new FileInputStream(file));
        md5=Md5Util.md5(in);
        dfsBaseInfo.setMd5Val(md5);
        in.close();
        dfsBaseInfo.setFileSize(fileSizeLong);

        dfsBaseInfo= md5Check(dfsBaseInfo);
        if (dfsBaseInfo!=null&& StringUtils.isNotEmpty(dfsBaseInfo.getMd5Val())) {
            DfsRelationShip drs = new DfsRelationShip();
            drs.setMd5Path(dfsBaseInfo.getMd5Val()+"@"+fileSizeLong);
            drs.setFileSrcSystem(moduleName);
            drs.setUserDfsId(userId);
            drs.setFileSrcName(fileName.contains(".")?fileName:fileName+"."+fileExt);
            drs.setIsDel("0");
            drs.setIsTemp("0");
            try {
                drs.setSrcIpAddr(InetAddress.getLocalHost().getHostAddress());
            } catch (UnknownHostException e) {
                e.printStackTrace();
            }
            drs.setXgrDm(userId);
            Instant instant = createDate.toInstant();
            ZoneId zone = ZoneId.systemDefault();
            drs.setXgrq(LocalDateTime.ofInstant(instant, zone));
            drs.setPrevPath(savePath);
            drs.setLrrDm(userId);
            drs.setBusinessId(bussinessId);
            try {
                drs.setSafeKey(getToken(fileName));
            } catch (Exception e) {
                e.printStackTrace();
            }
            drs.setFileType(URLConnection.getFileNameMap().getContentTypeFor(fileName+"."+fileExt));
            drs.setLrrq(LocalDateTime.now());
            drs.setId(snowflakeIdWorker.nextId());
            insertDfsRelationShip(drs);
        } else {
            DfsBaseInfo record = new DfsBaseInfo();
            DfsRelationShip drs = new DfsRelationShip();

            record.setMd5Val(md5);
            record.setFileExt(fileExt);
            record.setFileSize(fileSizeLong);
            record.setFileDownloadCount(0L);
            record.setRelateNum(0L);
            record.setLrrDm(userId);
            record.setLrrq(LocalDateTime.now());
            record.setXgrDm(moduleName);
            record.setXgrq(LocalDateTime.now());

            drs.setMd5Path(md5+"@"+fileSizeLong);
            drs.setFileSrcSystem(moduleName);
            drs.setUserDfsId(userId);
            drs.setFileSrcName(fileName.contains(".")?fileName:fileName+"."+fileExt);
            drs.setIsDel("0");
            drs.setIsTemp("0");
            try {
                drs.setSrcIpAddr(InetAddress.getLocalHost().getHostAddress());
            } catch (UnknownHostException e) {
                e.printStackTrace();
            }
            drs.setXgrDm(userId);

            Instant instant = createDate.toInstant();
            ZoneId zone = ZoneId.systemDefault();
            drs.setXgrq(LocalDateTime.ofInstant(instant, zone));

            drs.setFileSize(fileSizeLong);
            drs.setPrevPath(savePath);
            drs.setLrrDm(userId);
            drs.setBusinessId(bussinessId);
            try {
                drs.setSafeKey(getToken(fileName));
            } catch (Exception e) {
                e.printStackTrace();
            }
            drs.setFileType(URLConnection.getFileNameMap().getContentTypeFor(fileName+"."+fileExt));
            drs.setLrrq(LocalDateTime.now());
            drs.setId(snowflakeIdWorker.nextId());
            fileTransfer(file,record,drs );
        }
        DfsTransferStatus dfsTransferStatus=new DfsTransferStatus();
        dfsTransferStatus.setBussinessId(bussinessId);
        dfsTransferStatus.setSavePath(savePath);
        dfsTransferStatus.setFileName(fileName);
        dfsTransferStatus.setMd5Path(md5+"@"+fileSizeLong);
        dfsTransferStatus.setModuleName(moduleName);
        dfsTransferStatus.setSaveTime(fileMap.get("save_time")!=null?fileMap.get("save_time").toString():"");
        dfsTransferStatus.setMemo("成功");
        dfsTransferStatus.setCreateDate(LocalDateTime.now());
        dfsTransferStatus.setSavePath(savePath);
        dfsTransferStatus.setId(snowflakeIdWorker.nextId());
        dfsTransferStatus.setSuccessFlag("1");
        dfsTransferStatus.setUserId(userId);
        dfsTransferStatusService.save(dfsTransferStatus);
        log.debug(md5+"@"+fileSizeLong+",id: "+bussinessId+", save_path:"+savePath+"  文件上传结束,耗时："+((System.currentTimeMillis()-startTime)*1.0/1000)+"s");
        }catch (Exception e){
            DfsTransferStatus dfsTransferStatus=new DfsTransferStatus();
            dfsTransferStatus.setBussinessId(bussinessId);
            dfsTransferStatus.setSavePath(savePath);
            dfsTransferStatus.setFileName(fileName);
            dfsTransferStatus.setMd5Path("");
            dfsTransferStatus.setModuleName(moduleName);
            dfsTransferStatus.setSaveTime(fileMap.get("save_time")!=null?fileMap.get("save_time").toString():"");
            dfsTransferStatus.setMemo(e.toString());
            dfsTransferStatus.setCreateDate(LocalDateTime.now());
            dfsTransferStatus.setSavePath(savePath);
            dfsTransferStatus.setId(snowflakeIdWorker.nextId());
            dfsTransferStatus.setSuccessFlag("0");
            dfsTransferStatus.setUserId(userId);
            dfsTransferStatusService.save(dfsTransferStatus);
        }

    }

    public String getToken(String remote_filename)
    {
        byte[] buff=null;
        int ts = (int) Instant.now().getEpochSecond();
        byte[] bsFilename = new byte[0];
        try {
            bsFilename = remote_filename.getBytes("UTF-8");

        byte[] bsKey = secretKey.getBytes("UTF-8");
        byte[] bsTimestamp = (new Integer(ts)).toString().getBytes("UTF-8");

         buff= new byte[bsFilename.length + bsKey.length + bsTimestamp.length];
        System.arraycopy(bsFilename, 0, buff, 0, bsFilename.length);
        System.arraycopy(bsKey, 0, buff, bsFilename.length, bsKey.length);
        System.arraycopy(bsTimestamp, 0, buff, bsFilename.length + bsKey.length, bsTimestamp.length);
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        return DigestUtils.md5Hex(buff);
    }

    @Override
    public void convertOffice2PdfStream(DfsRelationShip drs, String waterMark, HttpServletResponse response) throws IOException, DocumentException {

        drs.setMd5Path(drs.getMd5Path().substring(0, drs.getMd5Path().indexOf("@")));
        dfsBaseInfoMapper.updateClick(drs);
        OutputStream out = response.getOutputStream();
        StorePath storePath = StorePath.praseFromUrl(drs.getFileId());

        String fileName =  drs.getFileSrcName().substring(0,drs.getFileSrcName().lastIndexOf(".")+1)+"pdf";
        response.addHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(fileName,"UTF-8"));
        String tempFile=
                System.getProperty("java.io.tmpdir") + "/upload_tmp" + UUID.randomUUID() + "."+ FilenameUtils.getExtension(drs.getFileSrcName()) ;
        storageClient.downloadFile(storePath.getGroup(), storePath.getPath(), new DownloadFileWriter(tempFile));
        String tempFile2=System.getProperty("java.io.tmpdir") + "/upload_tmp" + UUID.randomUUID() + ".pdf";
        File tempFilePdf=new File(tempFile2);
        doDocToFdpLibre(new File(tempFile),tempFilePdf);
        new File(tempFile).delete();
        if(StringUtils.isNotEmpty(waterMark)){
            PdfUtils.waterMarkerText(new PdfReader(new FileInputStream(tempFilePdf)),out,waterMark);
        }else{
            response.addHeader("Content-Length", tempFilePdf.length()+"");
            response.setContentLength((int)tempFilePdf.length());
            FileInputStream fis = new FileInputStream(tempFilePdf);
            byte[] buff = new byte[4096];
            int readed;
            while ((readed = fis.read(buff)) > 0) {
                out.write(buff, 0, readed);
            }
            fis.close();
            fis = null;

        }
        out.flush();
        tempFilePdf.delete();
        out.close();
    }

    @Override
    public String convertOffice2PdfStream(DfsRelationShip drs, String waterMark,String convertMode)  {

        String srcMd5=drs.getMd5Path().substring(0, drs.getMd5Path().indexOf("@"));
        Long srcFileSize=drs.getFileSize();
        drs.setMd5Path(srcMd5);

        dfsBaseInfoMapper.updateClick(drs);

        String fileSrcName = drs.getFileSrcName().substring(0, drs.getFileSrcName().lastIndexOf(".") + 1) + "pdf";
        StorePath storePath = StorePath.praseFromUrl(drs.getFileId());
        String fileSrcExt=FilenameUtils.getExtension(drs.getFileSrcName());
        String tempFile=
                System.getProperty("java.io.tmpdir") + "/upload_tmp" + UUID.randomUUID() + "."+ fileSrcExt ;
        storageClient.downloadFile(storePath.getGroup(), storePath.getPath(), new DownloadFileWriter(tempFile));

        String tempFile2=System.getProperty("java.io.tmpdir") + "/upload_tmp" + UUID.randomUUID() + ".pdf";
        File tempFilePdf=new File(tempFile2);

        if(convertMode.equals("wps")) {
            if(fileSrcExt.equalsIgnoreCase("xls")||fileSrcExt.equalsIgnoreCase("xlsx")){
                PdfUtils.wps_excel2pdf(tempFile,tempFilePdf.getAbsolutePath());
            }else{
                PdfUtils.wps_word2pdf(tempFile, tempFilePdf.getAbsolutePath());
            }
        }
        else
            doDocToFdpLibre(new File(tempFile),tempFilePdf);
        new File(tempFile).delete();

        Map data = new HashMap();

        File targetPdfFile = new File(
                System.getProperty("java.io.tmpdir") + "/upload_tmp" + UUID.randomUUID() + ".pdf");
        try {
          //  PdfUtils.modifyPdfAttribute(targetPdf.getAbsolutePath(),targetPdfFile.getAbsolutePath(),fileSrcName.substring(0,fileSrcName.length()-4),"szoa","szoa");

            PdfUtils.modifyPdfAttribute(tempFilePdf.getAbsolutePath(),targetPdfFile.getAbsolutePath(),"版式文件","szoa","szoa");
        } catch (DocumentException e) {
            e.printStackTrace();
            log.info(e.toString());
        } catch (IOException e) {
            e.printStackTrace();
        }
       try(InputStream in =new FileInputStream(targetPdfFile)) {
            log.debug(in.available()+"ddddddddddddddddddddddd");
            String md5 = Md5Util.md5(in);
            Long fileSize = targetPdfFile.length();
            data.put("md5", md5);
            data.put("fileSize", fileSize + "");
            data.put("fileSrcName", fileSrcName);
            data.put("fileExt", "pdf");
            data.put("md5Path",data.get("md5")+"@"+ data.get("fileSize"));
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        String pdfFileId=upload(null, targetPdfFile, data, true, true,true);
        data.put("md5",srcMd5);
        data.put("fileSize",srcFileSize);
        log.debug("ddddddddddddd"+srcMd5);
        dfsBaseInfoMapper.updatePdfPath(data);

        return data.get("md5Path").toString();
    }

    @Override
    public void convertTxt2PdfStream(DfsRelationShip drs, String waterMark, HttpServletResponse response) throws IOException {

        drs.setMd5Path(drs.getMd5Path().substring(0, drs.getMd5Path().indexOf("@")));
        dfsBaseInfoMapper.updateClick(drs);
        OutputStream out = response.getOutputStream();
        StorePath storePath = StorePath.praseFromUrl(drs.getFileId());

        String fileName =  drs.getFileSrcName().substring(0,drs.getFileSrcName().lastIndexOf(".")+1)+"pdf";
        response.addHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(fileName, "UTF-8"));
        storageClient.downloadFile(storePath.getGroup(), storePath.getPath(), new ConvertTxt2PdfStream(out,waterMark));
        out.flush();
        out.close();
    }

    @Transactional
    @Override
    public String convertTxt2PdfStream(DfsRelationShip drs, String waterMark,String docx) throws IOException {

        String srcMd5=drs.getMd5Path().substring(0, drs.getMd5Path().indexOf("@"));
        Long srcFileSize=drs.getFileSize();
        drs.setMd5Path(srcMd5);
        dfsBaseInfoMapper.updateClick(drs);

        File tempFile = new File(
                System.getProperty("java.io.tmpdir") + "/upload_tmp" + UUID.randomUUID() + ".pdf");
        String fileSrcName = drs.getFileSrcName().substring(0, drs.getFileSrcName().lastIndexOf(".") + 1) + "pdf";
        StorePath storePath = StorePath.praseFromUrl(drs.getFileId());
        try (OutputStream out=new FileOutputStream(tempFile)) {
            if(docx!=null&&docx.equals("1")) {
                String tempDocx=System.getProperty("java.io.tmpdir") +
                    "/upload_tmp" + UUID.randomUUID() + ".docx";
                storageClient.downloadFile(storePath.getGroup(),
                    storePath.getPath(),
                    new DownloadFileWriter(tempDocx));
                ByteArrayOutputStream tempOut=new ByteArrayOutputStream();
                try {
                    InputStream tempIns=new FileInputStream(tempDocx);
                    Doc2Docx.convertDocToPdf(tempIns, tempOut);
                    tempIns.close();
                    new File(tempDocx).delete();
                    ByteArrayInputStream swapStream =
                        new ByteArrayInputStream(tempOut.toByteArray());
                    IOUtils.copy(swapStream,out);
                } catch (Exception e) {
                    throw new IOException("转版失败");
                }
            }else
                storageClient.downloadFile(storePath.getGroup(), storePath.getPath(), new ConvertTxt2PdfStream(out, waterMark));
        }

        File targetPdfFile = new File(
                System.getProperty("java.io.tmpdir") + "/upload_tmp" + UUID.randomUUID() + ".pdf");
        try {
          //  PdfUtils.modifyPdfAttribute(tempFile.getAbsolutePath(),targetPdfFile.getAbsolutePath(),fileSrcName.substring(0,fileSrcName.length()-4),"szoa","szoa");
            PdfUtils.modifyPdfAttribute(tempFile.getAbsolutePath(),targetPdfFile.getAbsolutePath(),"版式文件","szoa","szoa");
        } catch (DocumentException e) {
            e.printStackTrace();
            log.info(e.toString());
        }
        tempFile.delete();
        Map data = new HashMap();
        try(InputStream in =new FileInputStream(targetPdfFile)) {
            String md5 = Md5Util.md5(in);
            Long fileSize = targetPdfFile.length();
            data.put("md5", md5);
            data.put("fileSize", fileSize + "");
            data.put("fileSrcName", fileSrcName);
            data.put("fileExt", "pdf");
            data.put("md5Path",data.get("md5")+"@"+ data.get("fileSize"));
        }
        String pdfFileId=upload(null, targetPdfFile, data, true, true,true);
        data.put("md5",srcMd5);
        data.put("fileSize",srcFileSize);
        dfsBaseInfoMapper.updatePdfPath(data);

        return data.get("md5Path").toString();
     }

    @Transactional
    @Override
    public String convertPic2PdfStream(DfsRelationShip drs, String waterMark) throws IOException {

        String srcMd5=drs.getMd5Path().substring(0, drs.getMd5Path().indexOf("@"));
        Long srcFileSize=drs.getFileSize();
        drs.setMd5Path(srcMd5);
        dfsBaseInfoMapper.updateClick(drs);

        File tempFile = new File(
                System.getProperty("java.io.tmpdir") + "/upload_tmp" + UUID.randomUUID() + drs.getFileSrcName().substring(drs.getFileSrcName().lastIndexOf(".")));
        String fileSrcName = drs.getFileSrcName().substring(0, drs.getFileSrcName().lastIndexOf(".") + 1) + "pdf";
        StorePath storePath = StorePath.praseFromUrl(drs.getFileId());
        storageClient.downloadFile(storePath.getGroup(), storePath.getPath(), new DownloadFileWriter(tempFile.getAbsolutePath()));

        File targetPdfFile = new File(
                System.getProperty("java.io.tmpdir") + "/upload_tmp" + UUID.randomUUID() + ".pdf");
        try (OutputStream fos=new FileOutputStream(targetPdfFile)) {
            String fileExt = FilenameUtils.getExtension(drs.getFileSrcName());
            if (!"tif".equals(fileExt.toLowerCase())){
                PdfUtils.jpg2pdf(tempFile.getAbsolutePath(), fos);
            }else {
                PdfUtils.tifToPdf(tempFile.getAbsolutePath(),fos);
            }
        }catch (Exception e){
            e.printStackTrace();
            log.error(e.toString());
        }
        File targetPdfFile1 = new File(
                System.getProperty("java.io.tmpdir") + "/upload_tmp" + UUID.randomUUID() + ".pdf");
        try {
            //  PdfUtils.modifyPdfAttribute(tempFile.getAbsolutePath(),targetPdfFile.getAbsolutePath(),fileSrcName.substring(0,fileSrcName.length()-4),"szoa","szoa");
            PdfUtils.modifyPdfAttribute(targetPdfFile.getAbsolutePath(),targetPdfFile1.getAbsolutePath(),"版式文件","szoa","szoa");
        } catch (DocumentException e) {
            e.printStackTrace();
            log.info(e.toString());
        }
        Map data = new HashMap();
        try(InputStream in =new FileInputStream(targetPdfFile1)) {
            String md5 = Md5Util.md5(in);
            Long fileSize = targetPdfFile1.length();
            data.put("md5", md5);
            data.put("fileSize", fileSize + "");
            data.put("fileSrcName", fileSrcName);
            data.put("fileExt", "pdf");
            data.put("md5Path",data.get("md5")+"@"+ data.get("fileSize"));
        }
        String pdfFileId=upload(null, targetPdfFile1, data, true, true,true);
        data.put("md5",srcMd5);
        data.put("fileSize",srcFileSize);
        dfsBaseInfoMapper.updatePdfPath(data);

        return data.get("md5Path").toString();
    }

    @Override
    public ReType selectByPrimaryKey(Long id) {
        return null;
    }

    @Override
    public void imagesToPdf(String[] md5Paths, String pdfName, HttpServletResponse response,   boolean isIE,String waterMark) throws IOException {
        String downloadName;
        pdfName=pdfName.replaceAll("%28","(").replaceAll("%29",")").replaceAll("%27","'").replaceAll("%21","!").replaceAll("%7E","~").replaceAll("%40","@").replaceAll("%23","#").replaceAll("%25","%").replaceAll("%26","&").replaceAll("%2B","+").replaceAll("%2A","*");
        if (isIE)
            downloadName = URLEncoder.encode(pdfName, "UTF-8");
        else
            downloadName=new String(pdfName.getBytes("UTF-8"), "ISO8859_1");
        String filename= System.getProperty("java.io.tmpdir") + "/upload_tmp" + UUID.randomUUID() + ".pdf";
        try{
            File targetPdfFile = new File(filename);
            Document document = new Document();
            document.setMargins(0, 0, 0, 0);
            PdfWriter.getInstance(document, new FileOutputStream(targetPdfFile));
            document.open();
            final int fileLength=md5Paths.length;
            for(int i=0;i<fileLength;i++){
                DfsRelationShip dfsRelationShip=new DfsRelationShip();
                dfsRelationShip.setMd5Path(md5Paths[i]);
                dfsRelationShip= dfsRelationShipMapper.selectByMd5Path(dfsRelationShip);
                File tempFile = new File(
                        System.getProperty("java.io.tmpdir") + "/upload_tmp" + UUID.randomUUID() + dfsRelationShip.getFileSrcName().substring(dfsRelationShip.getFileSrcName().lastIndexOf(".")));
                StorePath storePath = StorePath.praseFromUrl(dfsRelationShip.getFileId());
                storageClient.downloadFile(storePath.getGroup(), storePath.getPath(), new DownloadFileWriter(tempFile.getAbsolutePath()));
                if (tempFile.getPath().toLowerCase().endsWith("bmp")
                        ||tempFile.getPath().toLowerCase().endsWith("jpg")
                        ||tempFile.getPath().toLowerCase().endsWith("jpeg")
                        ||tempFile.getPath().toLowerCase().endsWith("gif")
                        ||tempFile.getPath().toLowerCase().endsWith("png")){
                    Image img = Image.getInstance(tempFile.getAbsolutePath());
                    img.setAlignment(Image.ALIGN_CENTER);
                  //  document.setPageSize(new Rectangle(PageSize.A4.rotate()));
                    document.setPageSize(new Rectangle(img.getWidth(), img.getHeight()));
                    document.newPage();
                    document.add(img);
                }else if (tempFile.getPath().toLowerCase().endsWith("tif")){
                    int tifFilePageCount = 0;// tif文件页数
                    File tifFile = new File(tempFile.getAbsolutePath());
                    InputStream tifFileInputStream  = new FileInputStream(tifFile);
                    RandomAccessFileOrArray randomAccessFile = new RandomAccessFileOrArray(tifFileInputStream);
                    tifFilePageCount = TiffImage.getNumberOfPages(randomAccessFile);
                    if (null != tifFileInputStream) {
                        tifFileInputStream.close();
                    }
                    for (int pageNumber = 1; pageNumber <= tifFilePageCount; pageNumber++) {
                        // 将tif文件读取成图片
                        Image tifImg = TiffImage.getTiffImage(randomAccessFile, pageNumber);
                        if (null == tifImg) {
                            throw new Exception("读取tif文件失败");
                        }
                        // 设置首页tif图片的大小
                        Rectangle firstpageSize = new Rectangle(tifImg.getWidth(), tifImg.getHeight());
                        document.setPageSize(firstpageSize);
                        // 设置图片大小
                        document.setPageSize(new Rectangle(tifImg.getWidth(), tifImg.getHeight()));
                        tifImg.setAlignment(Image.ALIGN_CENTER);// 设置图像的对齐方式(居中)。
                        document.newPage(); // 新建新的pdf页
                        document.add(tifImg);// 加载tif图片
                    }
                    if (null != randomAccessFile) {
                        randomAccessFile.close();
                    }
                }
            }
            document.close();
//            File pdfFile=new File(System.getProperty("java.io.tmpdir") + "/upload_tmp" + UUID.randomUUID() + ".pdf");
            File tempFilePdf = new File(filename);
            //修改pdf属性
//            PdfUtils.modifyPdfAttribute(tempFilePdf.getAbsolutePath(),pdfFile.getAbsolutePath(),"版式文件","szoa","szoa");
             //以流的形式下载文件。
            InputStream fis = new BufferedInputStream(new FileInputStream(tempFilePdf));
            byte[] buffer = new byte[fis.available()];
            fis.read(buffer);
            fis.close();
            response.reset();
            response.addHeader("Content-Disposition", "inline;filename=\"" + downloadName+"\"");
            //response.addHeader("Content-Disposition", "attachment;filename=" + new String(filename.getBytes()));
            response.addHeader("Content-Length", "" + tempFilePdf.length());
            OutputStream out = new BufferedOutputStream(response.getOutputStream());
            response.setContentType("application/pdf");
            out.write(buffer);
            out.flush();
            out.close();
        }catch (Exception e) {
            e.printStackTrace();
        }
        long startTime = System.currentTimeMillis();
        log.info("转pdf耗时: " + (System.currentTimeMillis() - startTime));
    }
    /**
     * @param md5Val
     * @return
     * @name 中文名称
     * @description 相关说明
     * @time 创建时间:2018年8月1日上午11:05:01
     * @author 作者 曹敏
     * @history 修订历史（历次修订内容、修订人、修订时间等）
     */
//    public DfsBaseInfo selectByPrimaryKey(String md5Val) {
//        //判断参数是否为空
//        if (StringUtils.isEmpty(md5Val)) {
//            throw new Exception("参数为空，请重新尝试");
//        }
//        //此时需要查询两张表的数据，
//        DfsBaseInfo dbi = dfsBaseInfoMapper.selectByPrimaryKey(md5Val);
//        if (dbi == null) {
//            throw new Exception("查询结果不存在，请稍后再试");
//        }
//        return dbi;
//    }

}
